module box_detect(
                input   wire            sclk,
                input   wire            resetb,
                
                input   wire            bd_clk,
                input   wire            bd_din,
                output  wire            bd_dout,
                input   wire            bd_en,

                input   wire    [7:0]   state_addr,
                output  wire    [7:0]   state_data,
                
                input   wire            read_eep_en,
                input   wire    [31:0]  read_eep_addr,                
                output  wire            eep_d_ok,
                output  wire    [7:0]   eep_data,
                                
                input   wire            set_state_ini,                        
                output  wire    [4:0]   set_state_ini_addr,
                input   wire    [7:0]   set_state_ini_data,
                
                output  wire	[7:0]	bd_wdata,
                output  wire		bd_wen,
                output  wire	[4:0]	bd_waddr,                  
                output  wire    [4:0]   bd_raddr,
                input   wire    [7:0]   bd_rdata                  
                );

reg     [3:0]   shift_clk,shift_din,shift_en;
wire            clk,din,en;

reg     [2:0]   base_count;
reg             rec_sync;
reg     [7:0]   rec_data;
reg             rec_write,rec_check;
reg     [3:0]   head_count;
reg     [15:0]  wr_length;
reg     [1:0]   wr_data_type;
reg     [31:0]  wr_opt_addr;
reg             rec_data_flag,send_data_flag;
reg     [7:0]   data_count;
wire            wen;
wire    [4:0]   waddr;
wire    [7:0]   wdata;
reg     [5:0]   send_length;
reg     [3:0]   send_data_type;
reg             send_flag;
reg     [7:0]   send_data;
reg             send_sync;
reg	[24:0]	detect_link_cnt=0;
wire		clr_ram_flag;
reg	[7:0]	tmp_wdata;
reg		tmp_wen;
reg	[4:0]	tmp_waddr;

always@(posedge sclk)
        begin
                shift_clk<={shift_clk[2:0],bd_clk};
                shift_din<={shift_din[1:0],bd_din};
                shift_en<={shift_en[1:0],bd_en};      
        end

assign  clk=shift_clk[2];
assign  din=shift_din[2];
assign  en=shift_en[2];

always@(posedge sclk)
        if(en==1)
                base_count<=0;
        else if(shift_clk[2:1]==2'b10)
                base_count<=base_count+1;

always@(posedge sclk)
        if(en==1)
                rec_sync<=1'b0;
        else if(base_count==7 && shift_clk[2:1]==2'b10)
                rec_sync<=1'b1;
        else
                rec_sync<=1'b0;       
                
always@(posedge sclk)
        if(en==1)
                rec_data<=8'h0;
        else if(shift_clk[3:2]==2'b01)
                rec_data<={rec_data[6:0],din};
                
// 接收箱体监控卡数据包解析                                  
always@(posedge sclk)
        if(en==1)
                head_count<=4'h0;
        else if((rec_write==1 || rec_check==1) && rec_sync==1'b1) begin
                if(head_count<4'hF)
                        head_count<=head_count+1;
                end
                              
always@(posedge sclk)
        if(en==1)
                rec_write<=0;
        else if(rec_write==1'b0 && head_count==0 && rec_sync==1 && rec_data==8'h55)                
                rec_write<=1;        

always@(posedge sclk)
        if(en==1)
                rec_check<=0;
        else if(rec_check==1'b0 && head_count==0 && rec_sync==1 && rec_data==8'hCC)                
                rec_check<=1;   
                                                        
always@(posedge sclk)
        if(en==1) begin
                wr_data_type    <=2'h0;
                wr_length       <=16'h0;
                wr_opt_addr     <=32'h0;
                end                
        else if(rec_write==1 && rec_sync==1)
                case(head_count)
                0:      wr_length[7:0]  <=rec_data;
                1:      wr_length[15:8] <=rec_data;      
                4:      wr_data_type    <=rec_data[1:0];
                5:      wr_opt_addr[7:0]<=rec_data;
                6:      wr_opt_addr[15:8]<=rec_data;
                7:      wr_opt_addr[23:16]<=rec_data;
                8:      wr_opt_addr[31:24]<=rec_data;
                endcase
                
always@(posedge sclk)
        if(en==1)
                rec_data_flag<=0;
        else if(rec_sync==1'b1) begin
                if(rec_write==1 && head_count==8)
                        rec_data_flag<=1;
                else if(rec_write==1 && data_count==wr_length-'d9)
                        rec_data_flag<=0;
                end

always@(posedge sclk)
        if(en==1)
                send_data_flag<=0;
        else if(rec_sync==1'b1) begin
                if(send_flag==1 && head_count==13)
                        send_data_flag<=1;
                else if(send_flag==1'b0)
                        send_data_flag<=0;
                end
                                
always@(posedge sclk)
        if(en==1)
                data_count<=0;
        else if((rec_data_flag==1 && rec_sync==1'b1)||(send_data_flag==1 && send_sync==1'b1))
                data_count<=data_count+1;

always@(posedge sclk)
	if(rec_check=='d0 && {detect_link_cnt[24],detect_link_cnt[4:0]}!=6'b111111)
		detect_link_cnt<=detect_link_cnt+'d1;
	else if(rec_check=='d1) 
		detect_link_cnt<='d0; 
		
assign	clr_ram_flag=detect_link_cnt[24]; 	               
// 从箱体监控卡接收数据 
//状态寄存器数据                
assign  wen=(wr_data_type==1)?  rec_sync&rec_data_flag:0;
assign  waddr=data_count[4:0];
assign  wdata=rec_data;

always@ *
	if(clr_ram_flag)
		tmp_wen<=clr_ram_flag;
	else
		tmp_wen<=wen;
always@ *
	if(clr_ram_flag)
		tmp_waddr<=detect_link_cnt[4:0];
	else
		tmp_waddr<=waddr;
always@ *
	if(clr_ram_flag)
		tmp_wdata<='d0;
	else
		tmp_wdata<=wdata;


assign  bd_wdata=tmp_wdata;
assign  bd_wen=tmp_wen;
assign  bd_waddr=tmp_waddr;
assign  bd_raddr={~state_addr[4],state_addr[3:0]};
assign  state_data=bd_rdata;
	                
//sram_32_8 state_reg_sram(
//	.data(tmp_wdata),
//	.rdaddress({~state_addr[4],state_addr[3:0]}),
//	.rdclock(sclk),
//	.wraddress(tmp_waddr),
//	.wrclock(sclk),
//	.wren(tmp_wen),
//	.q(state_data));
	
//EEPROM数据
//assign  eep_d_ok=(wr_data_type==2)?   rec_sync&rec_data_flag:0;  
//assign  eep_data=rec_data;

// 向箱体监控卡发送数据  
always@(posedge sclk)
        if(set_state_ini==1)
                send_length<=40;
        else if(read_eep_en==1)                                
                send_length<=8;
        else
                send_length<=3;

always@(posedge sclk)
        if(set_state_ini==1)
                send_data_type[3:0]<=4'h9;
        else if(read_eep_en==1)                                
                send_data_type[3:0]<=4'hA;
        else
                send_data_type[3:0]<=0;

assign  set_state_ini_addr=data_count[4:0];
                                
always@(posedge sclk)
        if(en==1)
                send_flag<=0;
        else if(rec_check==1'b1 && head_count==4 && rec_sync==1)                
                send_flag<=1; 	         
        else if((set_state_ini==1 && data_count==send_length-8) || (set_state_ini==0 && head_count==4'hD) && rec_sync==1)
                send_flag<=0;

always@(posedge sclk)
        send_sync<=rec_sync;

always@(posedge sclk)
        if(en==1)
                send_data<=0;       
        else if(rec_check==1'b1 && send_data_flag==1'b0 && send_sync==1)
                case(head_count)
                4'h5:      send_data<={2'h0,send_length};              
                4'h9:      send_data<={4'h0,send_data_type};
                //4'hA:      send_data<=read_eep_addr[7:0];
                //4'hB:      send_data<=read_eep_addr[15:8];
                //4'hC:      send_data<=read_eep_addr[23:9]; 
                //4'hD:      send_data<=read_eep_addr[31:24];
                default:         send_data<=0;        
                endcase           
        else if(rec_check==1'b1 && send_data_flag==1'b1 && send_sync==1)
                send_data<=set_state_ini_data;
        else if(shift_clk[2:1]==2'b10)
                send_data<={send_data[6:0],1'b0};

assign  bd_dout=(send_flag==0)? 0:send_data[7];               
                                              
endmodule